package org.kabeja.dxf.helpers;

import org.kabeja.dxf.entity.DXFPolyline;
import org.kabeja.dxf.entity.DXFVertex;
import org.kabeja.math.MathUtils;

/**
 * @author shutao
 * @since 2022/4/25 10:34
 */
public class PolylineSegment {
    public static double DELTA = 0.001D;
    private boolean bulged = false;
    private Point point1 = new Point();
    private Point point2 = new Point();
    private Point point3 = new Point();
    private Point point4 = new Point();
    private double radius;
    private double bulgeHeight;
    private double innerRadius;
    private double outerRadius;
    private DXFVertex start;
    private DXFPolyline p;

    public PolylineSegment(DXFVertex var1, DXFVertex var2, DXFPolyline var3) {
        this.start = var1;
        this.p = var3;
        if (this.start.getBulge() != 0.0D) {
            double var4 = MathUtils.distance(var1.getPoint(), var2.getPoint());
            this.radius = this.getRadius(Math.abs(var1.getBulge()), var4);
            this.bulgeHeight = var1.getBulge() * var4 / 2.0D;
            this.setBulged(true);
            this.createCurvedTrapezium(var1, var2, this.radius, var4);
        } else {
            this.createTrapezium(var1, var2);
        }

    }

    public double getBulge() {
        return this.start.getBulge();
    }

    public boolean isBulged() {
        return this.bulged;
    }

    public void setBulged(boolean var1) {
        this.bulged = var1;
    }

    public Point getPoint1() {
        return this.point1;
    }

    public void setPoint1(Point var1) {
        this.point1 = var1;
    }

    public Point getPoint2() {
        return this.point2;
    }

    public void setPoint2(Point var1) {
        this.point2 = var1;
    }

    public Point getPoint3() {
        return this.point3;
    }

    public void setPoint3(Point var1) {
        this.point3 = var1;
    }

    public Point getPoint4() {
        return this.point4;
    }

    public void setPoint4(Point var1) {
        this.point4 = var1;
    }

    public double getRadius() {
        return this.radius;
    }

    public void setRadius(double var1) {
        this.radius = var1;
    }

    protected void createCurvedTrapezium(DXFVertex var1, DXFVertex var2, double var3, double var5) {
        double var7 = var5 / 2.0D;
        Vector var9 = MathUtils.getVector(var1.getPoint(), var2.getPoint());
        var9 = MathUtils.normalize(var9);
        Point var10 = MathUtils.getPointOfStraightLine(var1.getPoint(), var9, var7);
        Vector var11 = this.p.getExtrusion().getNormal();
        var11 = MathUtils.crossProduct(var11, var9);
        var11 = MathUtils.normalize(var11);
        double var12 = Math.abs(var1.getBulge() * var5) / 2.0D;
        double var14 = this.p.getRadius(var1.getBulge(), var5);
        boolean var16 = false;
        double var17;
        if (var1.getBulge() > 0.0D) {
            var17 = var12 - var14;
            var10 = MathUtils.getPointOfStraightLine(var10, var11, var17);
        } else {
            var16 = true;
            var17 = var14 - var12;
            var10 = MathUtils.getPointOfStraightLine(var10, var11, var17);
        }

        var17 = 0.0D;
        if (var1.getStartWidth() > 0.0D) {
            var17 = var1.getStartWidth() / 2.0D;
        } else {
            var17 = this.p.getStartWidth() / 2.0D;
        }

        if (var1.getBulge() > 0.0D) {
            var17 = -1.0D * var17;
        }

        var11 = MathUtils.getVector(var1.getPoint(), var10);
        var11 = MathUtils.normalize(var11);
        this.point1 = MathUtils.getPointOfStraightLine(var1.getPoint(), var11, var17);
        this.point2 = MathUtils.getPointOfStraightLine(var1.getPoint(), var11, var17 * -1.0D);
        if (var1.getEndWidth() > 0.0D) {
            var17 = var1.getEndWidth() / 2.0D;
        } else {
            var17 = this.p.getEndWidth() / 2.0D;
        }

        if (var1.getBulge() > 0.0D) {
            var17 = -1.0D * var17;
        }

        var11 = MathUtils.getVector(var2.getPoint(), var10);
        var11 = MathUtils.normalize(var11);
        this.point3 = MathUtils.getPointOfStraightLine(var2.getPoint(), var11, var17 * -1.0D);
        this.point4 = MathUtils.getPointOfStraightLine(var2.getPoint(), var11, var17);
    }

    protected void createTrapezium(DXFVertex var1, DXFVertex var2) {
        double var3 = 0.0D;
        if (var1.getStartWidth() > 0.0D) {
            var3 = var1.getStartWidth() / 2.0D;
        } else {
            var3 = this.p.getStartWidth() / 2.0D;
        }

        Vector var5 = this.p.getExtrusion().getNormal();
        Vector var6 = MathUtils.getVector(var1.getPoint(), var2.getPoint());
        var5 = MathUtils.crossProduct(var5, var6);
        var5 = MathUtils.normalize(var5);
        this.point1 = MathUtils.getPointOfStraightLine(var1.getPoint(), var5, var3);
        this.point2 = MathUtils.getPointOfStraightLine(var1.getPoint(), var5, -1.0D * var3);
        if (var1.getEndWidth() > 0.0D) {
            var3 = var1.getEndWidth() / 2.0D;
        } else {
            var3 = this.p.getEndWidth() / 2.0D;
        }

        this.point3 = MathUtils.getPointOfStraightLine(var2.getPoint(), var5, -1.0D * var3);
        this.point4 = MathUtils.getPointOfStraightLine(var2.getPoint(), var5, var3);
    }

    protected double getRadius(double var1, double var3) {
        double var5 = var1 * var3 / 2.0D;
        return var5 / 2.0D + Math.pow(var3, 2.0D) / (8.0D * var5);
    }

    public double getBulgeHeight() {
        return this.bulgeHeight;
    }

    public void connect(PolylineSegment var1) {
        Vector var2 = MathUtils.getVector(this.point1, this.point4);
        Vector var3 = MathUtils.getVector(var1.getPoint4(), var1.getPoint1());
        double var4 = MathUtils.getAngle(var2, var3);
        if (Math.abs(var4) > DELTA) {
            Point var6 = MathUtils.getIntersection(this.point1, var2, var1.getPoint4(), var3);
            this.setPoint4(var6);
            var1.setPoint1(var6);
            var2 = MathUtils.getVector(this.point2, this.point3);
            var3 = MathUtils.getVector(var1.getPoint3(), var1.getPoint2());
            var6 = MathUtils.getIntersection(this.point2, var2, var1.getPoint3(), var3);
            this.setPoint3(var6);
            var1.setPoint2(var6);
        }

    }

    public double getInnerRadius() {
        double var1 = (this.start.getStartWidth() + this.start.getEndWidth()) / 2.0D;
        if (var1 == 0.0D) {
            var1 = (this.p.getStartWidth() + this.p.getEndWidth()) / 2.0D;
        }

        return this.getRadius() - var1;
    }

    public double getOuterRadius() {
        double var1 = (this.start.getStartWidth() + this.start.getEndWidth()) / 2.0D;
        if (var1 == 0.0D) {
            var1 = (this.p.getStartWidth() + this.p.getEndWidth()) / 2.0D;
        }

        return this.getRadius() + var1;
    }
}
